<html>
<head><meta charset="utf-8"><title>Strange behavior of never type around raw ptr deref and &quot;_&quot; · t-lang/project-never-type · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/259160-t-lang/project-never-type/index.html">t-lang/project-never-type</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/259160-t-lang/project-never-type/topic/Strange.20behavior.20of.20never.20type.20around.20raw.20ptr.20deref.20and.20.22_.22.html">Strange behavior of never type around raw ptr deref and &quot;_&quot;</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="218939063"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/259160-t-lang/project-never-type/topic/Strange%20behavior%20of%20never%20type%20around%20raw%20ptr%20deref%20and%20%22_%22/near/218939063" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/259160-t-lang/project-never-type/topic/Strange.20behavior.20of.20never.20type.20around.20raw.20ptr.20deref.20and.20.22_.22.html#218939063">(Dec 05 2020 at 15:16)</a>:</h4>
<p>I just found out some very strange behavior of the <code>!</code> type, which I think can only be a bug: <a href="https://github.com/rust-lang/rust/issues/79735">https://github.com/rust-lang/rust/issues/79735</a><br>
Or at least I see no way to explain the current behavior in a sound (as in, type-safe) way, except for applying very different semantics to <code>!</code> and <code>enum Void {}</code>, which would be surprisingly inconsistent to say the least.<br>
I am curious what the never-type people here think of this :)</p>



<a name="218960132"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/259160-t-lang/project-never-type/topic/Strange%20behavior%20of%20never%20type%20around%20raw%20ptr%20deref%20and%20%22_%22/near/218960132" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/259160-t-lang/project-never-type/topic/Strange.20behavior.20of.20never.20type.20around.20raw.20ptr.20deref.20and.20.22_.22.html#218960132">(Dec 06 2020 at 00:03)</a>:</h4>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">fn</span> <span class="nf">foo</span><span class="p">(</span><span class="n">ptr</span>: <span class="o">*</span><span class="k">const</span><span class="w"> </span><span class="kt">bool</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">*</span><span class="n">ptr</span><span class="p">;</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<p>That's an interesting example.  It's arguably a regression in safety checking -- it was an error in 1.16.0.</p>



<a name="218960195"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/259160-t-lang/project-never-type/topic/Strange%20behavior%20of%20never%20type%20around%20raw%20ptr%20deref%20and%20%22_%22/near/218960195" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/259160-t-lang/project-never-type/topic/Strange.20behavior.20of.20never.20type.20around.20raw.20ptr.20deref.20and.20.22_.22.html#218960195">(Dec 06 2020 at 00:05)</a>:</h4>
<p>I would expect it to be equivalent to <code>intrinsics::assume(ptr != 0)</code>, even if the place isn't later used.  (Like if it were <code>*const String</code> it wouldn't try to move out of it because of the <code>_</code>, but would still conceptually dereference it.)</p>



<a name="218960199"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/259160-t-lang/project-never-type/topic/Strange%20behavior%20of%20never%20type%20around%20raw%20ptr%20deref%20and%20%22_%22/near/218960199" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/259160-t-lang/project-never-type/topic/Strange.20behavior.20of.20never.20type.20around.20raw.20ptr.20deref.20and.20.22_.22.html#218960199">(Dec 06 2020 at 00:05)</a>:</h4>
<p>But maybe this was an intentional change...</p>



<a name="218960462"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/259160-t-lang/project-never-type/topic/Strange%20behavior%20of%20never%20type%20around%20raw%20ptr%20deref%20and%20%22_%22/near/218960462" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/259160-t-lang/project-never-type/topic/Strange.20behavior.20of.20never.20type.20around.20raw.20ptr.20deref.20and.20.22_.22.html#218960462">(Dec 06 2020 at 00:12)</a>:</h4>
<p>(It makes me think of those bugs where we ended up adding an always-there discriminant check in some place to make sure that something ends up in the MIR to be checked, even if optimizations removed it later...)</p>



<a name="218980247"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/259160-t-lang/project-never-type/topic/Strange%20behavior%20of%20never%20type%20around%20raw%20ptr%20deref%20and%20%22_%22/near/218980247" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/259160-t-lang/project-never-type/topic/Strange.20behavior.20of.20never.20type.20around.20raw.20ptr.20deref.20and.20.22_.22.html#218980247">(Dec 06 2020 at 10:29)</a>:</h4>
<p><span class="user-mention silent" data-user-id="125270">scottmcm</span> <a href="#narrow/stream/259160-t-lang.2Fproject-never-type/topic/Strange.20behavior.20of.20never.20type.20around.20raw.20ptr.20deref.20and.20.22_.22/near/218960195">said</a>:</p>
<blockquote>
<p>I would expect it to be equivalent to <code>intrinsics::assume(ptr != 0)</code>, even if the place isn't later used.  (Like if it were <code>*const String</code> it wouldn't try to move out of it because of the <code>_</code>, but would still conceptually dereference it.)</p>
</blockquote>
<p>so you would <em>not</em> expect it to demand that the <code>bool</code> is 0x00 or 0x01?</p>



<a name="219017955"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/259160-t-lang/project-never-type/topic/Strange%20behavior%20of%20never%20type%20around%20raw%20ptr%20deref%20and%20%22_%22/near/219017955" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/259160-t-lang/project-never-type/topic/Strange.20behavior.20of.20never.20type.20around.20raw.20ptr.20deref.20and.20.22_.22.html#219017955">(Dec 06 2020 at 21:04)</a>:</h4>
<p>Well, past-Scott certainly would have expected it, since past-Scott didn't know that <code>_</code> had different semantics from <code>_foo</code>...</p>
<p>I don't know what I expect now.  With <code>let _ = &amp;*ptr;</code> I probably would expect it to demand that, since it made the reference and the reference can be spuriously dereferenced.  But we expect that <code>ptr::raw_const!(*p)</code> works without looking behind the pointer (just doing address math), right?  So maybe that pushes me to thinking that just "making" the place doesn't demand the validity invariant of the pointee.</p>
<p>Hmm, to add to the weirdness, this <em>doesn't</em> compile despite not <em>looking</em> like it does anything different:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">fn</span> <span class="nf">foo</span><span class="p">(</span><span class="n">ptr</span>: <span class="o">*</span><span class="k">const</span><span class="w"> </span><span class="kt">bool</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="o">*</span><span class="n">ptr</span><span class="p">;</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>